

import json
import datetime
import xlrd
from openpyxl import Workbook



class data_item:
    def __init__(self) -> None:
        self.uid = ""                   # 用户标识
        self.shape = ""                 # 选择的形状  例如: A
        self.select_mode = "default"    # 选择的模式  例如: A1/A2
        self.seq_index = 0              # 模式的序列  例如: 0,1
        self.round = 0                  # 回合
        self.enter_cards_time = 0       # 进入卡片页面的时间
        self.cards_seq = []             # 卡片序列
        self.std_anwer = []           # 卡片序列中的标准答案 #
        self.click_seq = []           # 用户选择的3张卡片序列
        self.leave_cards_time = 0       # 离开卡片页面的时间
        self.click_diff_time = 0        # 选3张卡片需要的时间  #
        self.click_result = None        # 是否选择正确 # 
        self.enter_ack_time = 0         # 进入记忆确认页面的时间
        self.ack_answer = None          # 确认的答案
        self.ack_result_1 = 0             # 是否回答正确        # 与所选择的比
        self.ack_result_2 = 0             # 是否回答正确        # 与标准的比
        self.leave_ack_time = 0         # 离开记忆确认页面的时间
        self.ack_diff_time = 0          # 输完答案的时间       #

    def title():
        l = []
        uid = "用户id"                   # 用户标识
        shape = "选择的形状"
        select_mode = "选择的模式"    # 选择的模式  例如: A
        seq_index = "序号"              # 模式的序列  例如: A1/A2
        enter_cards_time = "进入卡片页面时间"       # 进入卡片页面的时间
        cards_seq = "卡片序列"           # 卡片序列
        std_anwer = "卡片答案"           # 卡片序列中的标准答案 #
        click_seq = "点击的3张卡片"           # 用户选择的3张卡片序列
        leave_cards_time = "离开卡片页面的时间"       # 离开卡片页面的时间
        click_diff_time = "点3张图需要的时间"        # 选3张卡片需要的时间  #
        click_result = "是否选择正确"               # 是否选择正确
        enter_ack_time = "进入确认页面需要的时间"         # 进入记忆确认页面的时间
        ack_answer = "确认的答案"          # 确认的答案
        ack_result_1 = "是否回答正确(与选择的比)"         # 与选择的比  
        ack_result_2 = "是否回答正确(与标准的比)"         # 与标准的比
        leave_ack_time = "离开确认页面的时间"         # 离开记忆确认页面的时间
        ack_diff_time = "确认答案的耗时"          # 输完答案的时间

        l.append(uid)
        l.append(shape)
        l.append(select_mode)
        l.append(seq_index)
        l.append(enter_cards_time)
        l.append(cards_seq)
        l.append(std_anwer)
        l.append(click_seq)
        l.append(leave_cards_time)
        l.append(click_diff_time)
        l.append(click_result)
        l.append(enter_ack_time)
        l.append(ack_answer)
        l.append(ack_result_1)
        l.append(ack_result_2)
        l.append(leave_ack_time)
        l.append(ack_diff_time)
        return l
    
    # # 计算序列的答案
    # def calculate_seq_answer(self):
    #     answer_str = ""
    #     for seq in self.cards_seq:
    #         if self.shape == seq[0]:
    #             answer_str = answer_str + seq[1]
    #     self.std_anwer = answer_str
    #     return answer_str

    # 计算序列的答案
    def calculate_seq_answer(self):
        answer_str = []
        for seq in self.cards_seq:
            if self.shape == seq[0]:
                answer_str.append(seq)
        
        self.std_anwer = answer_str
        return answer_str

    # 计算时间差
    def calculate_time_diff(self):
        self.click_diff_time = self.leave_cards_time - self.enter_cards_time
        self.ack_diff_time = self.leave_ack_time - self.enter_ack_time
    
    # 计算是否回答正确
    def calculate_whether_correct(self):
        l_ack_answer = []
        for c in self.ack_answer:
            t = self.shape + c
            l_ack_answer.append(t)
        
        if l_ack_answer == self.click_seq:
            self.ack_result_1 = "正确"
        else:
            self.ack_result_1 = "错误"
        
        if l_ack_answer == self.std_anwer:
            self.ack_result_2 = "正确"
        else:
            self.ack_result_2 = "错误"

        if self.click_seq == self.std_anwer:
            self.click_result = "正确"
        else:
            self.click_result = "错误"


    def _list_to_string(self, a_list):
        l_list = []
        l_list = a_list
        s = ""
        l = len(l_list)
        for i in range(l):
            s = s + l_list[i]
            if (i + 1) != l:
                s = s + ", "
        return s

    # 将list成员转成字符串
    def list_member_to_string(self):
        # print(self.cards_seq)
        self.cards_seq = self._list_to_string(self.cards_seq)
        # print(self.click_seq)
        self.click_seq = self._list_to_string(self.click_seq)
        # print(self.std_anwer)
        self.std_anwer = self._list_to_string(self.std_anwer)

    # 将毫秒时间转日期字符串
    def _ms_to_string(self, ms):
        l_ms = int(ms)
        time_local = datetime.datetime.fromtimestamp(l_ms / 1000)
        dt = time_local.strftime("%Y-%m-%d %H:%M:%S.%f")
        return dt

    def cast_to_list(self):
        # 计算序列的答案
        self.calculate_seq_answer()
        # 计算时间差
        self.calculate_time_diff()
        # 计算是否回答正确
        self.calculate_whether_correct()
        # 将list成员转成字符串
        self.list_member_to_string()

        result = []
        result.append(str(self.uid))
        result.append(str(self.shape))
        result.append(str(self.select_mode))
        result.append(str(self.seq_index))
        result.append(self._ms_to_string(self.enter_cards_time))
        result.append(str(self.cards_seq))
        result.append(str(self.std_anwer))
        result.append(str(self.click_seq))
        result.append(self._ms_to_string(self.leave_cards_time))
        result.append(str(self.click_diff_time))
        result.append(str(self.click_result))
        result.append(self._ms_to_string(self.enter_ack_time))
        result.append(str(self.ack_answer))
        result.append(str(self.ack_result_1))
        result.append(str(self.ack_result_2))
        result.append(self._ms_to_string(self.leave_ack_time))
        result.append(str(self.ack_diff_time))
        return result


# 读取原始数据
def read_origin_data():
    items = []
    lines = []
    data = None
    with open("./wgy_lab2_20201117.data", "r") as f:
        for l in f:
            zv = json.loads(l)
            pre_handle(zv)
            lines.append(zv)

    lines.reverse()
    for d in lines:
        item = handle_data(d)
        items.extend(item)
    return items

# 预处理数据
def pre_handle(line):
    std_str = "ack:answer:"
    mode = ""
    index = 0
    round = ""
    temp = None
    for k in line.keys():
        index = k.find(std_str)
        if -1 != index:
            temp = k.split(std_str)[1].split(":")
            mode = temp[0]
            # round = temp[2]
            line["select_mode"] = mode
            # line["round"] = round
            # print(temp)
            # print(mode)
            # print(round)
            break


# 处理数据
def handle_data(dict_msg):
    shape = ""
    mode = ""
    round = range(0, 5)
    index = range(0, 20)
    suffix = ""
    mode = dict_msg.get("select_mode", "u")
    shape = mode[0]

    uid = dict_msg.get("uid", "undefine")
    items = []
    for i in index:
        for r in round:
            suffix = mode + ":" + str(i) + ":" + str(r)
            suffix_1 = shape + suffix
            # print(suffix)
            item = data_item()
            item.uid = uid
            item.shape = shape
            item.select_mode = mode
            item.seq_index = str(i)
            # 进入卡片页面时间
            key = "enter:cards:page:time:" + suffix_1
            if key in dict_msg.keys():
                value = dict_msg[key]
                item.enter_cards_time = int(value)

            # 卡片序列
            key = "seq:" + suffix_1
            if key in dict_msg.keys():
                value = dict_msg[key]
                dl = json.loads(value)
                item.cards_seq = dl

            # 用户选择的3张卡片序列
            key = "click:seq:" + suffix
            if key in dict_msg.keys():
                value = dict_msg[key]
                dl = json.loads(value)
                item.click_seq = dl

            # 离开卡片页面时间
            key = "leave:cards:page:time:" + suffix
            if key in dict_msg.keys():
                value = dict_msg[key]
                item.leave_cards_time = int(value)

            # 进入记忆确认页面的时间
            key = "enter:ack:page:time:" + suffix
            if key in dict_msg.keys():
                value = dict_msg[key]
                item.enter_ack_time = int(value)

            # 确认的答案
            key = "ack:answer:" + suffix
            if key in dict_msg.keys():
                value = dict_msg[key]
                item.ack_answer = value
            
            # 离开记忆确认页面的时间
            key = "leave:ack:page:time:" + suffix
            if key in dict_msg.keys():
                value = dict_msg[key]
                item.leave_ack_time = int(value)
                items.append(item)
    return items




def handle():
    items = read_origin_data()
    wb = Workbook()
    ws = wb.active
    ws.append(data_item.title())
    
    for item in items:
        r = item.cast_to_list()
        ws.append(r)
    
    wb.save("zhao_test.xlsx")

handle()





